// 打开文件 open
// open 静态方法能够以只读模式（read-only mode）打开一个文件。
//
// File 拥有资源，即文件描述符（file descriptor），它会在自身被 drop 时关闭文件。

mod file {
    use std::fs::File;
    use std::io;
    use std::io::{BufRead, Read, Write};
    use std::path::Path;

    pub fn open_file(filename: &str) {
        // 创建指向所需的文件的路径
        let path = Path::new(filename);
        let display = path.display();
        // 以只读方式打开路径，返回 `io::Result<File>`
        let mut file = match File::open(&path) {
            Ok(file) => file,
            // `io::Error` 的 `description` 方法返回一个描述错误的字符串。
            Err(why) => panic!("couldn't open {}: {:?}", display, why),
        };

        // 读取文件内容到一个字符串，返回 `io::Result<usize>`
        let mut s = String::new();
        match file.read_to_string(&mut s) {
            Err(why) => panic!("couldn't read {}: {:?}", display, why),
            Ok(_) => print!("{} contains:\n{}", display, s),
        }
        // `file` 离开作用域，并且 `hello.txt` 文件将被关闭。
    }

    pub fn create_file(data: &str, filename: &str) {
        let path = Path::new(filename);
        let display = path.display();

        // 以只写模式打开文件，返回 `io::Result<File>`
        let mut file = match File::create(&path) {
            Err(why) => panic!("couldn't create {}: {:?}", display, why),
            Ok(file) => file,
        };

        // 将 `LOREM_IPSUM` 字符串写进 `file`，返回 `io::Result<()>`
        match file.write_all(data.as_bytes()) {
            Err(why) => {
                panic!("couldn't write to {}: {:?}", display, why)
            }
            Ok(_) => println!("successfully wrote to {}", display),
        }
    }
    pub fn read_lines_data(filename:&str){
        if let Ok(lines) = read_lines(filename) {
            for line in lines {
                if let Ok(msg) = line {
                    println!("{}", msg);
                }
            }
        }
    }

    fn read_lines<P>(filename:P) -> io::Result<io::Lines<io::BufReader<File>>>
    where P:AsRef<Path>,{
        let file = File::open(filename)?;
        Ok(io::BufReader::new(file).lines())
    }
}

#[cfg(test)]
mod tests {
    use super::file;

    #[test]
    fn test_open() {
        let filename: &str = "./hello.txt";
        file::open_file(filename);
    }

    #[test]
    fn test_create() {
        let filename = "./abc.txt";
        let lorem_ipsum = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
";
        file::create_file(lorem_ipsum, filename);
    }

    #[test]
    fn test_read_lines(){
        let filename = "./abc.txt";
        file::read_lines_data(filename);
    }
}